package org.dromara.hotel.dubbo;

import com.alibaba.nacos.shaded.com.google.common.collect.Iterators;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.hotel.domain.TerHotelRooms;
import org.dromara.hotel.domain.TerPriceCalendar;
import org.dromara.hotel.domain.TerPricingRule;
import org.dromara.hotel.domain.bo.TerPricingRuleBo;
import org.dromara.hotel.mapper.TerHotelRoomsMapper;
import org.dromara.hotel.mapper.TerPriceCalendarMapper;
import org.dromara.hotel.mapper.TerPricingRuleMapper;
import org.dromara.hotel.service.ITerPricingRuleService;
import org.dromara.tearoom.api.RemoteBatchCalendar;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@RequiredArgsConstructor
@Service
@DubboService
public class RemoteBatchCalendarImpl implements RemoteBatchCalendar {
    private final TerHotelRoomsMapper baseMapper;
    private final TerPriceCalendarMapper priceMapper;
    private final TerPricingRuleMapper ruleMapper;
    private final ITerPricingRuleService ruleService;
    public void generateCalendarPrices() {

        LocalDate start = LocalDate.now().withDayOfMonth(1);
        LocalDate end = start.plusMonths(3);
        // 分页查询房型
        int pageSize = 100;
        Page<TerHotelRooms> page = new Page<>(1, pageSize);
        IPage<TerHotelRooms> roomTypePage;
        LambdaQueryWrapper<TerPricingRule> lqw = Wrappers.lambdaQuery();

        do {
            roomTypePage = baseMapper.selectPage(page, null);
            List<TerPriceCalendar> allPrices = new ArrayList<>();
            roomTypePage.getRecords().forEach(roomType -> {
                lqw.eq(TerPricingRule::getRoomId, roomType.getId());
                List<TerPricingRule> activeRules = ruleMapper.selectList(lqw);
                List<TerPriceCalendar> prices = IntStream.range(0, (int) ChronoUnit.DAYS.between(start, end))
                    .mapToObj(offset -> {
                        LocalDate date = start.plusDays(offset);
                        Integer price = ruleService.getDailyPrice(roomType.getId(), date,activeRules);
                        TerPriceCalendar tpc= new TerPriceCalendar();
                        tpc.setRoomId(roomType.getId());
                        tpc.setPriceDay(date);
                        tpc.setFinalPrice(price);
                        tpc.setAvailableQuantity(roomType.getTotalQuantity());
                        tpc.setSource(1);
                        return tpc;
                    })
                    .collect(Collectors.toList());

                allPrices.addAll(prices);
            });
            priceMapper.truncateTable();
            // 批量插入优化（每5000条提交一次）
            Iterators.partition(allPrices.iterator(), 5000)
                .forEachRemaining(batch -> priceMapper.batchInsert(batch));
            page.setCurrent(page.getCurrent() + 1);
        } while (roomTypePage.getRecords().size() == pageSize);
    }
}
